package com.project.easy.common.framework.web.filter;

import  com.project.easy.common.util.collection.CollectionUtil;
import  com.project.easy.common.util.dto.ApiContextParam;
import  com.project.easy.common.util.dto.FilterDto;
import  com.project.easy.common.util.enums.exception.ValidatorExceptionEnums;
import  com.project.easy.common.util.filter.WebAuthFilter;
import com.project.easy.common.framework.web.entity.dto.WebAuthFilterDto;
import com.project.easy.common.framework.web.exception.ParamValidatorException;
import com.project.easy.common.framework.web.validator.ValidatorTool;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Objects;

/**
* @Author: yangchao.cool
* @Date: 2022/7/19 22:52
 * Description: 权限认证
*/
@Component
public class ParamWebAuthFilter extends WebAuthFilter {
    /**
     * 过滤器执行方法
     *
     * @param request  请求
     * @param response 响应
     * @param param    参数
     * @return 返回结果
     */
    @Override
    public FilterDto doFilter(HttpServletRequest request, HttpServletResponse response, FilterDto param) {
        WebAuthFilterDto filterDto =  (WebAuthFilterDto) param;
        if (!Objects.isNull(filterDto.getApiValidator()) && filterDto.getApiValidator().hasParam()) {
            validatorParam(filterDto.getPoint());
        }
        if (!Objects.isNull(filterDto.getParamValidator()) && !Objects.isNull(filterDto.getParamValidator())) {
            validatorParam(filterDto.getPoint());
        }
        return filterDto;
    }
    /**
     * 验证参数
     * @param jp 拦截点
     */
    private void validatorParam(ProceedingJoinPoint jp) {
        Object[] args = jp.getArgs();
        MethodSignature methodSignature = (MethodSignature) jp.getSignature();
        Method method = methodSignature.getMethod();
        Object group = null;
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();

        if (!CollectionUtil.isNull(parameterAnnotations)) {
            for (Annotation[] annotations :  parameterAnnotations) {
                for (Annotation annotation : annotations) {
                    if (annotation instanceof Validated) {
                        group = ((Validated) annotation).value();
                    }
                }
            }
        }
        if (!CollectionUtil.isNull(args)) {
            for (Object arg : args) {
                if (arg instanceof ApiContextParam) {
                    if (Objects.isNull(((ApiContextParam) arg).getPubHeader())) {
                        throw new ParamValidatorException(ValidatorExceptionEnums.VALIDATOR_PARAM_ILLEGAL.getCode(), "请求头公共参数不能为空");
                    }
                    if (Objects.nonNull(group)) {
                        ValidatorTool.validate(arg, group.getClass());
                    } else {
                        ValidatorTool.validateParams(arg);
                    }
                }
            }
        }
    }
}
